package cxy.highConcurrency;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * FutureTask——ft1 和 ft2，ft1 完成洗水壶、烧开水、泡茶的任务，ft2 完成洗茶壶、洗茶杯、拿茶叶的任务； 这里需要注意的是 ft1
 * 这个任务在执行泡茶任务前，需要等待 ft2 把茶叶拿来，所以 ft1 内部需要引用 ft2， 并在执行泡茶之前，调用 ft2 的 get()
 * 方法实现等待。
 * 
 * @author admin
 *
 */
public class FutureTaskDemo {
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		// 创建任务T2的FutureTask
		FutureTask<String> ft2 = new FutureTask<>(new T2Task());
		// 创建任务T1的FutureTask
		FutureTask<String> ft1 = new FutureTask<>(new T1Task(ft2));
		
		// 线程T1执行任务ft1
		Thread T1 = new Thread(ft1);
		T1.start();
		// 线程T2执行任务ft2
		Thread T2 = new Thread(ft2);
		T2.start();
		// 等待线程T1执行结果
		System.out.println(ft1.get());
		
	}
	
	
	static class T2Task implements Callable<String> {
		@Override
		public String call() throws Exception {
			System.out.println("T2:洗茶壶..."); 
			TimeUnit.SECONDS.sleep(1); 
			System.out.println("T2:洗茶杯..."); 
			TimeUnit.SECONDS.sleep(2);
			System.out.println("T2:拿茶叶..."); 
			TimeUnit.SECONDS.sleep(1); 
			return "龙井";
		}
		
	}

	static class T1Task implements Callable<String> {
		FutureTask<String> ft2;

		// T1任务需要T2任务的FutureTask
		T1Task(FutureTask<String> ft2) {
			this.ft2 = ft2;
		}

		@Override
		public String call() throws Exception {
			System.out.println("T1:洗水壶...");
			TimeUnit.SECONDS.sleep(1);
			System.out.println("T1:烧开水...");
			TimeUnit.SECONDS.sleep(15);
			
			// 获取T2线程的茶叶，阻塞方法
			String tf = ft2.get();
			
			System.out.println("T1:拿到茶叶:" + tf);
			System.out.println("T1:泡茶...");
			return "上茶:" + tf;
		}
	}

}
